package ui.graphical;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusListener;
import java.awt.event.MouseListener;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.border.BevelBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import logic.Logic;
import logic.rule.ReserveringRules;
import domain.Deelnemer;
import domain.DeelnemerPK;
import domain.Persoon;
import domain.Reservering;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;

public class Reserveringen extends GuiBaseFrame implements ActionListener, MouseListener, FocusListener {

	private static final long serialVersionUID = -8374800377275480784L;

	private JButton btnZoek;
	private JLabel lblZoekReservering;
	private JPanel reserveringPanel;
	private JTextField txtBoekdatum;
	private JTextField txtReisnaam;
	private JTextField txtAnnuleringsdatum;
	private JTextField txtDagenVerlenging;
	private JTextField txtVerlengingskosten;
	private JTextField txtBetaaldatum;
	private JTextField txtGeboektDoor;
	private JTextField txtVertrekdatum;
	private JTextField txtAantalDeelnemers;
	private JCheckBox chckbxVluchtverlenging;
	private JCheckBox chckbxBetaald;

	private JButton btnDeelnemerToevoegen;

	private JList listDeelnemer;
	private JTextField txtTotaal;
	private JLabel lblTotaalprijs;
	private JComboBox cbxPersonen;
	
	public Reserveringen(Logic logic) {
		super(logic, "Reserveringen");
			
		createGUI();
	}
	

	protected void dispatchList(Object object) {
		reserveer2Scherm((Reservering) object);
	}
	
	public void actionPerformed(ActionEvent e) {
		
		super.actionPerformed(e);
		
		if(e.getSource().equals(zoekVeld)||e.getSource().equals(btnZoek)) {
			zoekReservering();
		}
		
		else if(e.getSource().equals(btnToevoegen)) {
			UIHelper.errorMsg("Niet geimplementeerd");
		}
		else if(e.getSource().equals(btnOpslaan)) {
			saveReservering();
		}
		else if(e.getSource().equals(btnVerwijderen)) {
			verwijderReservering();
		} 		
		else if(e.getSource().equals(btnDeelnemerToevoegen)) {
			voegDeelnemerToe();
		}


		
	}
	private void zoekReservering() {

		List<Reservering> results = logic.zoekReserveringen("%"+zoekVeld.getText()+"%");
		((DefaultListModel)listOverview.getModel()).removeAllElements();
		for(Reservering reservering: results) {
			((DefaultListModel)listOverview.getModel()).addElement(reservering);
		}
		
	}
	

	
	private void verwijderReservering() {
		Reservering reservering = (Reservering) getSelectedObject();
		if(reservering!=null) {
			if(UIHelper.confirm("Weet u zeker dat u deze reservering wilt annuleren?")) {
				try {
					/**
					 * W007 Eenmaal geannuleerde boekingen mogen niet opnieuw geactiveerd worden
					 * 		Dit is door de bouw van de applicatie niet mogelijk. 
					 * 		Er is in de applicatie geen mogelijkheid de canceldatum handmatig aan te passen
					 */
					reservering.setCanceldatum(Calendar.getInstance().getTime());
					ReserveringRules.checkReservering(reservering);
					logic.saveReservering(reservering);
					zoekReservering();
				} catch (SQLException e) {
					UIHelper.errorMsg(e.getMessage());
				}
			}
		} else {
			UIHelper.errorMsg("U heeft geen reservering geselecteerd");
		}
	}
	
	private void saveReservering() {
		if(UIHelper.confirm("Weet u zeker dat u deze reservering wilt opslaan?")) {
			Reservering reservering = (Reservering) getSelectedObject();
			if(reservering==null) {
				UIHelper.errorMsg("U hebt geen reservering geselecteerd");
			} else {
				try {
					scherm2Reservering(reservering);
					ReserveringRules.checkReservering(reservering);
					logic.saveReservering(reservering);
					zoekReservering();
				} catch (SQLException e) {
					UIHelper.errorMsg(e.getMessage());
				}
			}
		}
	}
	

	private void reserveer2Scherm(Reservering reservering) {
		txtBoekdatum.setText((reservering!=null)?UIHelper.date2string(reservering.getBoekingsdatum()):"");
		txtAnnuleringsdatum.setText((reservering!=null)?UIHelper.date2string(reservering.getCanceldatum()):"");
		txtBetaaldatum.setText((reservering!=null)?UIHelper.date2string(reservering.getBetaaldatum()):"");
		txtReisnaam.setText((reservering!=null)?reservering.getPlanning().getReis().getReistype():"");
		txtVertrekdatum.setText((reservering!=null)?UIHelper.date2string(reservering.getPlanning().getStartdatum()):"");
		txtDagenVerlenging.setText(((reservering!=null)?Integer.toString(reservering.getAantalVerlengingsDagen()):""));
		txtVerlengingskosten.setText(((reservering!=null)?reservering.getVluchtverlengingsKosten().toString():""));
		txtGeboektDoor.setText((reservering!=null)?reservering.getGeboekt_door().toString():"");
		txtAantalDeelnemers.setText(((reservering!=null)?Integer.toString(reservering.getAantaldeelnemers()):""));
		if(reservering!=null && reservering.getVluchtverlenging()==1){
			chckbxVluchtverlenging.setSelected(true);
		} else {
			chckbxVluchtverlenging.setSelected(false);
		}
		
		if(reservering!=null && reservering.getBetaald()==1){
			chckbxBetaald.setSelected(true);
		} else {
			chckbxBetaald.setSelected(false);
		}
		vulListDeelnemers(reservering);
	}
	
	private void vulListDeelnemers(Reservering reservering) {
		((DefaultListModel)listDeelnemer.getModel()).removeAllElements();
		if(reservering!=null) {
			Set<Deelnemer> deelnemers = reservering.getDeelnemers(); 
			for(Deelnemer deelnemer: deelnemers) {
				((DefaultListModel)listDeelnemer.getModel()).addElement(deelnemer.getPersoon());
			}
			berekenPrijs(reservering);
			txtTotaal.setText(reservering.getPrijs().toString());
		}
		
		cbxPersonen.removeAllItems();
		List<Persoon> personen = logic.getDeelnemers();
		cbxPersonen.addItem(null);
		for(Persoon persoon: personen) {
			cbxPersonen.addItem(persoon);
		}
		
	}
	
	private void scherm2Reservering(Reservering reservering) {
		if(chckbxVluchtverlenging.isSelected()) {
			reservering.setVluchtverlenging((byte) 1);
			reservering.setAantalVerlengingsDagen(Integer.parseInt(txtDagenVerlenging.getText()));
			reservering.setVluchtverlengingsKosten(BigDecimal.valueOf(Double.parseDouble(txtVerlengingskosten.getText())));
		} else {
			reservering.setVluchtverlenging((byte) 0);
		}
	}
	
	
	private void voegDeelnemerToe() {
		/**
		 * W008 Aan een reservering kan een nieuwe deelnemer worden toegevoegd.
		 * 		Het bedrag van de reservering wordt automatisch herberekend.
		 * 		Het maximum aantal deelnemers aan een reis mag niet worden overschreden.
		 */
		Reservering reservering = (Reservering) getSelectedObject();
		if(reservering!=null) {
			Persoon persoon = (Persoon)cbxPersonen.getSelectedItem();
			if(persoon!=null) {
				reservering.setDeelnemers(reservering.getDeelnemers()); // Forceer update van berekende waarden om zeker te weten dat deze kloppen ivm 2NV database
				
				if(!ReserveringRules.checkMaxDeelnemersBereikt(reservering)) { //W008 Het maximum aantal deelnemers aan een reis mag niet worden overschreden.
					Deelnemer deelnemer = new Deelnemer();
					deelnemer.setReservering(reservering);
					deelnemer.setPersoon(persoon);
					try {
						Set<Deelnemer> deelnemers = reservering.getDeelnemers();
						deelnemers.add(deelnemer);
						reservering.setDeelnemers(deelnemers);
						berekenPrijs(reservering); //W008 Het bedrag van de reservering wordt automatisch herberekend.
						logic.saveReservering(reservering);
						vulListDeelnemers(reservering);
					} catch (SQLException e) {
						UIHelper.errorMsg("Deelnemer kon niet gekoppeld worden");
					}
				} else {
					UIHelper.errorMsg("Maximaal aantal deelnemers bereikt voor deze reis");
				}
			} else {
				UIHelper.errorMsg("Je hebt geen nieuwe deelnemer geselecteerd");
			}
		} else {
			UIHelper.errorMsg("Je hebt geen reservering geselecteerd");
			
		}
	}
	
	private void berekenPrijs(Reservering reservering) {
		if(reservering!=null) {
			reservering.setDeelnemers(reservering.getDeelnemers()); // Forceer update van berekende waarden om zeker te weten dat deze kloppen ivm 2NV datamodel
			BigDecimal kortingspercentage =  logic.getKorting(reservering.getAantaldeelnemers()).getKorting().divide(new BigDecimal(100));
			BigDecimal prijs = reservering.getPlanning().getPrijs();
			
			prijs = prijs.subtract(prijs.multiply(kortingspercentage));
			prijs = prijs.multiply(new BigDecimal(reservering.getAantaldeelnemers()));
			reservering.setPrijs(prijs);
			
			
			
		}
	}

	private void createGUI() {
		
		btnVerwijderen.setText("Annuleer");
		btnToevoegen.setEnabled(false);
		
		lblZoekReservering = new JLabel("Zoek reservering");
		lblZoekReservering.setBounds(10, 14, 87, 14);
		getContentPane().add(lblZoekReservering);
		
		reserveringPanel = new JPanel();
		reserveringPanel.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
		reserveringPanel.setBounds(10, 257, 331, 307);
		getContentPane().add(reserveringPanel);
		reserveringPanel.setLayout(null);
		
		JLabel lblBoekdatum = new JLabel("Boekdatum");
		lblBoekdatum.setBounds(10, 11, 105, 14);
		reserveringPanel.add(lblBoekdatum);
		
		JLabel lblReisnaam = new JLabel("Reisnaam");
		lblReisnaam.setBounds(10, 36, 77, 14);
		reserveringPanel.add(lblReisnaam);
		
		JLabel lblAnnuleringsdatum = new JLabel("Annuleringsdatum");
		lblAnnuleringsdatum.setBounds(10, 92, 105, 14);
		reserveringPanel.add(lblAnnuleringsdatum);
		
		JLabel lblDagenVerlenging = new JLabel("Dagen verlenging");
		lblDagenVerlenging.setBounds(120, 129, 105, 14);
		reserveringPanel.add(lblDagenVerlenging);
		
		JLabel lblVerlengingskosten = new JLabel("Verlengingskosten");
		lblVerlengingskosten.setBounds(120, 154, 105, 14);
		reserveringPanel.add(lblVerlengingskosten);
		
		JLabel lblBetaaldatum = new JLabel("Betaaldatum");
		lblBetaaldatum.setBounds(120, 202, 77, 14);
		reserveringPanel.add(lblBetaaldatum);
		
		JLabel lblGeboektDoor = new JLabel("Geboekt door");
		lblGeboektDoor.setBounds(10, 233, 77, 14);
		reserveringPanel.add(lblGeboektDoor);
		
		JLabel lblVertrekdatum = new JLabel("Vertrekdatum");
		lblVertrekdatum.setBounds(10, 64, 77, 14);
		reserveringPanel.add(lblVertrekdatum);
		
		txtBoekdatum = new JTextField();
		txtBoekdatum.setEnabled(false);
		txtBoekdatum.setEditable(false);
		txtBoekdatum.setBounds(125, 8, 86, 20);
		reserveringPanel.add(txtBoekdatum);
		txtBoekdatum.setColumns(10);
		
		txtReisnaam = new JTextField();
		txtReisnaam.setEnabled(false);
		txtReisnaam.setEditable(false);
		txtReisnaam.setBounds(125, 33, 196, 20);
		reserveringPanel.add(txtReisnaam);
		txtReisnaam.setColumns(10);
		
		txtAnnuleringsdatum = new JTextField();
		txtAnnuleringsdatum.setEnabled(false);
		txtAnnuleringsdatum.setEditable(false);
		txtAnnuleringsdatum.setBounds(125, 89, 86, 20);
		reserveringPanel.add(txtAnnuleringsdatum);
		txtAnnuleringsdatum.setColumns(10);
		
		chckbxVluchtverlenging = new JCheckBox("Vluchtverlenging");
		chckbxVluchtverlenging.setBounds(2, 137, 114, 23);
		reserveringPanel.add(chckbxVluchtverlenging);
		
		chckbxBetaald = new JCheckBox("Betaald");
		chckbxBetaald.setEnabled(false);
		chckbxBetaald.setBounds(2, 198, 97, 23);
		reserveringPanel.add(chckbxBetaald);
		
		txtDagenVerlenging = new JTextField();
		txtDagenVerlenging.setBounds(235, 126, 86, 20);
		reserveringPanel.add(txtDagenVerlenging);
		txtDagenVerlenging.setColumns(10);
		
		txtVerlengingskosten = new JTextField();
		txtVerlengingskosten.setBounds(235, 151, 86, 20);
		reserveringPanel.add(txtVerlengingskosten);
		txtVerlengingskosten.setColumns(10);
		
		txtBetaaldatum = new JTextField();
		txtBetaaldatum.setEnabled(false);
		txtBetaaldatum.setEditable(false);
		txtBetaaldatum.setBounds(235, 199, 86, 20);
		reserveringPanel.add(txtBetaaldatum);
		txtBetaaldatum.setColumns(10);
		
		txtGeboektDoor = new JTextField();
		txtGeboektDoor.setEnabled(false);
		txtGeboektDoor.setEditable(false);
		txtGeboektDoor.setBounds(125, 230, 196, 20);
		reserveringPanel.add(txtGeboektDoor);
		txtGeboektDoor.setColumns(10);
		
		txtVertrekdatum = new JTextField();
		txtVertrekdatum.setEnabled(false);
		txtVertrekdatum.setEditable(false);
		txtVertrekdatum.setBounds(125, 61, 86, 20);
		reserveringPanel.add(txtVertrekdatum);
		txtVertrekdatum.setColumns(10);
		
		txtAantalDeelnemers = new JTextField();		
		txtAantalDeelnemers.setEnabled(false);
		txtAantalDeelnemers.setEditable(false);
		txtAantalDeelnemers.setBounds(125, 258, 86, 20);
		reserveringPanel.add(txtAantalDeelnemers);
		txtAantalDeelnemers.setColumns(10);
		
		JLabel lblAantalDeelnemers = new JLabel("Aantal deelnemers");
		lblAantalDeelnemers.setBounds(10, 261, 105, 14);
		reserveringPanel.add(lblAantalDeelnemers);
		
		btnZoek = new JButton("Zoek");
		btnZoek.setBounds(295, 10, 89, 23);
		getContentPane().add(btnZoek);
		btnZoek.addActionListener(this);
		
		
		JPanel deelnemerPanel = new JPanel();
		deelnemerPanel.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
		deelnemerPanel.setBounds(355, 257, 429, 307);
		getContentPane().add(deelnemerPanel);
		deelnemerPanel.setLayout(null);

		JLabel lblPlanningsoverzicht = new JLabel("Deelnemers");
		lblPlanningsoverzicht.setBounds(10, 15, 65, 14);
		deelnemerPanel.add(lblPlanningsoverzicht);
		
		btnDeelnemerToevoegen = new JButton("Toevoegen");
		btnDeelnemerToevoegen.addActionListener(this);
		btnDeelnemerToevoegen.setBounds(329, 11, 95, 23);
		deelnemerPanel.add(btnDeelnemerToevoegen);
		
		getContentPane().add(deelnemerPanel);
		
		txtTotaal = new JTextField();
		txtTotaal.setBounds(338, 278, 86, 20);
		deelnemerPanel.add(txtTotaal);
		txtTotaal.setColumns(10);
		
		lblTotaalprijs = new JLabel("Totaalprijs");
		lblTotaalprijs.setBounds(242, 281, 86, 14);
		deelnemerPanel.add(lblTotaalprijs);
		
		listDeelnemer = new JList(new DefaultListModel());
		listDeelnemer.setBounds(20, 40, 404, 228);
		deelnemerPanel.add(listDeelnemer);
		
		cbxPersonen = new JComboBox();
		cbxPersonen.setBounds(85, 12, 238, 20);
		deelnemerPanel.add(cbxPersonen);


	}
}
